<?php
class Book extends Zend_Db_Table_Abstract {
	
	protected $_primary = 'id';
	protected $_name = 'book';
	
	protected $_dependentTables = array(
        'UserBook'
    );
	
    /**
     * Find all books.
     */
    public function findAll() {
    	return $this->fetchAll($this->select());
    }
    
	/**
	 * Add book. 
	 * 
	 * @param $data
	 * @return book id
	 */
	public function addBook($data) {
		$obj = $this->findByASIN($data["ASIN"]);
		if (empty($obj)) {
			$obj = $this->createRow($data);
			$id = $obj->save();
			return $id;
		} else {
			return $obj->id;
		}
	}
	
	/**
	 * Find book by id.
	 * 
	 * @param $id
	 */
	public function findById($id) {
		return $this->find($id)->current();
	}
	
	/**
	 * Find book in database by asin.
	 * 
	 * @param $asin
	 * @return return book
	 */
	public function findByASIN($asin) {
		$select = $this->select()->where('ASIN=?', $asin);
		return $this->fetchRow($select);
	}
	
	/**
	 * Return users who have the given book.
	 * 
	 * @param $book
	 * @param $status user book status
	 * @param $city top city object
	 * @return return users list who have the given book
	 */
	public static function getUser($book, $status, $city=null) {
		$userBook = new UserBook();
		if (empty($status)) {
			if (empty($city)) {
				return $book->findManyToManyRowset('User', 'UserBook', 'Book', 'User', $userBook->select()->order('i.created DESC'));
			} else {
				$subCities = City::getSubCityIdArray($city->id);
				if (empty($subCities)) {
					return $book->findManyToManyRowset('User', 'UserBook', 'Book', 'User', $userBook->select()->where("location=?", $city->id)->order('i.created DESC'));
				} else {
				    return $book->findManyToManyRowset('User', 'UserBook', 'Book', 'User', $userBook->select()->where("location=".$city->id." OR location in (".implode(",",$subCities).")")->order('i.created DESC'));
				}
			}
		} else {
			if (empty($city)) {
				return $book->findManyToManyRowset('User', 'UserBook', 'Book', 'User', $userBook->select()->where('i.status=?', $status)->order('i.created DESC'));
			} else {
				$subCities = City::getSubCityIdArray($city->id);
                if (empty($subCities)) {
                	return $book->findManyToManyRowset('User', 'UserBook', 'Book', 'User', $userBook->select()->where('i.status=?', $status)->where("location=?", $city->id)->order('i.created DESC'));
                } else {
				    return $book->findManyToManyRowset('User', 'UserBook', 'Book', 'User', $userBook->select()->where('i.status=?', $status)->where("location=".$city->id." OR location in (".implode(",",$subCities).")")->order('i.created DESC'));
                }
			}
		}
	}
	
    /**
     * Get lucene search fields.
     * 
     * @param $invitation invitation
     */
    public static function _getSearchIndexFields($book) {
        $fields = array();
        $fields[Custom_Search_Lucene_Document::CLASS_NAME] = 'Book';
        $fields[Custom_Search_Lucene_Document::KEY] = $book->id;
        $fields[Constant::BOOK_OBJ] = $book;
        return $fields;
    }
    
    /**
     * Check if the use has given book.
     * 
     * @param $book
     * @param $user
     * @return return true if given user has given book
     */
    public static function userHasBook($book, $user) {
    	$userBook = new UserBook();
        $rowset = $book->findDependentRowset("UserBook", "Book", $userBook->select()->where("user_id=?", $user->id));
        return count($rowset) > 0;
    }
    
    /**
     * Find user book map of a book by given user, it should return ONE and ONLY ONE entry.
     * 
     * @param $book
     * @param $user
     */
    public static function getUserBook($book, $user) {
    	$userBook = new UserBook();
    	$rowset = $book->findDependentRowset("UserBook", "Book", $userBook->select()->where("user_id=?", $user->id));
    	return $rowset->current();
    }

    public static function getAvailableUserBook($book, $user) {
    	$userBook = new UserBook();
    	$rowset = $book->findDependentRowset("UserBook", "Book", $userBook->select()->where("user_id=?", $user->id)->where('status=?', UserBookStatus::AVAILABLE));
    	return $rowset->current();
    }
    
    /**
     * Return list of userBook that have the given book.
     * 
     * @param $book
     */
    public static function getUserBooks($book) {
    	$userBook = new UserBook();
        return $book->findDependentRowset("UserBook", "Book", $userBook->select()->where('status=?', UserBookStatus::AVAILABLE));
    }
    
    /**
     * Return 8 top/most popular available books.
     * 
     * @param $cityId cityid, like stockholm, it must be the top city
     */
    public static function getTopBooks($cityId, $num=8) {
    	// select count(*) as num, book_id from book join user_book on book.id=user_book.book_id join user on user.id=user_book.user_id where user.city=1 and user_book.status='available' group by book_id order by num desc;
    	$table = new Book();
        $select = $table->select(Zend_Db_Table::SELECT_WITH_FROM_PART)
        ->setIntegrityCheck(false)
        ->from(array("b"=>"book"), array("ASIN" =>"b.ASIN", "num"=>"count(*)"))
        ->join(array("ub" => "user_book"), "b.id=ub.book_id")
        ->joinLeft(array("u" => "user"), "u.id=ub.user_id");
    	$subCities = City::getSubCityIdArray($cityId);
    	if (!empty($subCities)) { 
    		$select = $select->where("u.location=".$cityId." OR u.location IN (".implode(",",City::getSubCityIdArray($cityId)).")");
    	} else {
    		$select = $select->where("u.location=?", $cityId);
    	}
        $select = $select->where("ub.status=?", UserBookStatus::AVAILABLE)
        ->group("b.id")
        ->order("num DESC")
        ->limit($num,0);
        $ret = array();
        foreach ($table->fetchAll($select) as $result) {
            $ret[$result->ASIN] = $table->findByASIN($result->ASIN);
        }
        return $ret;
    }
}
?>